using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using UnityEngine;
using Newtonsoft.Json;
using System.Threading;
using Newtonsoft.Json.Linq;

public class PythonSocketClient : MonoBehaviour
{
    private TcpClient socketClient;
    private NetworkStream stream;
    private bool isConnected = false;
    private Thread receiveThread;
    
    // 缓存未完成的JSON数据
    private StringBuilder jsonBuffer = new StringBuilder();
    
    [Header("自动重连设置")]
    [Tooltip("自动重连间隔（秒）")]
    public float autoReconnectInterval = 5.0f;
    
    private bool isResetting = false; // 标记是否正在重置
    private bool isAutoConnecting = false; // 标记自动连接协程是否正在运行
    
    // 数据队列：用于在主线程处理接收到的数据
    private Queue<DataPacks> receivedDataQueue = new Queue<DataPacks>();
    private object queueLock = new object();

    public OptimizedHexGrid hexGrid;
    public List<AutoScanner> autoScanners;
    public LeaderController LeaderController;

    [Header("发送间隔设置(秒)")]
    [Tooltip("网格数据发送间隔，建议2-5秒（熵值变化慢）")]
    public float gridDataSendInterval = 1.0f; // 网格数据发送间隔（优化：1秒→3秒）

    [Tooltip("运行时数据发送间隔，建议0.1-0.2秒")]
    public float runtimeDataSendInterval = 0.15f; // 运行时数据发送间隔（优化：0.1秒→0.15秒）
    
    [Header("优化设置")]
    [Tooltip("是否只发送变化的网格数据（Delta更新）")]
    public bool useDeltaGridUpdate = true;

    private readonly Rect buttonArea = new Rect(20, 20, 150, 100); // 按钮区域位置和大小
    private readonly float buttonHeight = 30;                      // 按钮高度
    private readonly float buttonSpacing = 10;                     // 按钮间距

    private float lastGridDataSendTime;
    private float lastRuntimeDataSendTime;
    
    // Delta更新：记录上次发送的熵值
    private Dictionary<Vector3, float> lastSentEntropy = new Dictionary<Vector3, float>();
    
    // 标记是否已发送过完整网格数据
    private bool hassentInitialGridData = false;

    public void StartConnection()
    {
        Connect();
    }

    public void Start()
    {
        // 初始化数据队列和JSON缓冲区
        receivedDataQueue = new Queue<DataPacks>();
        jsonBuffer = new StringBuilder();
        
        // 启动自动连接协程
        StartCoroutine(AutoConnectCoroutine());
    }

    // 自动连接协程 - 永久运行，自动重连
    IEnumerator AutoConnectCoroutine()
    {
        isAutoConnecting = true;
        
        while (true)
        {
            // 如果未连接，尝试连接
            if (!isConnected)
            {
                Debug.Log($"[自动连接] 尝试连接到Python服务器...");
                Connect();
                
                // 等待指定间隔后再次检查
                yield return new WaitForSeconds(autoReconnectInterval);
            }
            else
            {
                // 已连接，每秒检查一次连接状态
                yield return new WaitForSeconds(1f);
            }
        }
    }

    // 连接到服务器
    private void Connect(string ip = "localhost", int port = 5000)
    {
        try
        {
            socketClient = new TcpClient(ip, port);
            stream = socketClient.GetStream();
            isConnected = true;

            // 启动接收线程
            receiveThread = new Thread(ReceiveData);
            receiveThread.IsBackground = true;
            receiveThread.Start();
            Debug.Log("[连接] ✅ 成功连接到Python服务器");

            // 初始化发送时间
            lastGridDataSendTime = Time.time;
            lastRuntimeDataSendTime = Time.time;
            
            // 重置Delta状态，确保首次发送完整数据
            lastSentEntropy.Clear();
            hassentInitialGridData = false;
            
            // 清空JSON缓冲区
            jsonBuffer.Clear();
            
            // 启动Leader和HexGrid
            if (LeaderController != null)
            {
                LeaderController.IsStart = true;
            }
            if (hexGrid != null)
            {
                hexGrid.IsStart = true;
                Debug.Log("[连接] 已启动熵值计算");
            }
        }
        catch (Exception e)
        {
            Debug.LogWarning($"[连接] 连接服务器失败: {e.Message}");
            isConnected = false;
        }
    }

    // 断开连接
    private void Disconnect()
    {
        isConnected = false;
        
        // 停止Leader和HexGrid
        if (LeaderController != null)
        {
            LeaderController.IsStart = false;
        }
        if (hexGrid != null)
        {
            hexGrid.IsStart = false;
        }
        
        if (receiveThread != null && receiveThread.IsAlive)
        {
            receiveThread.Abort();
        }

        stream?.Close();
        socketClient?.Close();
        
        // 清空接收队列和JSON缓冲区
        lock (queueLock)
        {
            receivedDataQueue.Clear();
        }
        jsonBuffer.Clear();
        
        Debug.Log("[断开] 已断开与Python服务器的连接");
    }

    private void OnDestroy()
    {
        isAutoConnecting = false; // 停止自动连接
        Disconnect();
    }

    private void Update()
    {
        // 处理接收队列中的数据（在主线程中）
        lock (queueLock)
        {
            while (receivedDataQueue.Count > 0)
            {
                var dataPacks = receivedDataQueue.Dequeue();
                ProcessReceivedData(dataPacks);
            }
        }
        
        if (!isConnected) return;
        
        // 重置期间停止发送数据
        if (isResetting) return;

        // 首次连接：立即发送完整网格数据
        if (!hassentInitialGridData)
        {
            SendGridData();
            hassentInitialGridData = true;
            Debug.Log("[初始化] 已发送完整网格数据给Python");
        }

        // 按不同间隔分开发送网格数据和运行时数据
        if (Time.time - lastGridDataSendTime >= gridDataSendInterval)
        {
            lastGridDataSendTime = Time.time;
            SendGridData(); // 后续发送增量数据
        }

        if (Time.time - lastRuntimeDataSendTime >= runtimeDataSendInterval)
        {
            lastRuntimeDataSendTime = Time.time;
            SendRuntimeData(); // 仅发送运行时数据
        }
    }


    #region 发送数据

    // 仅发送网格数据
    public void SendGridData()
    {
        if (!isConnected || hexGrid == null) return;

        try
        {
            HexGridModel hexGridModel;
            bool isInitialSend = lastSentEntropy.Count == 0;
            
            // 首次发送：发送完整数据
            if (isInitialSend)
            {
                hexGridModel = new HexGridModel(hexGrid);
                
                // 记录所有熵值
                foreach (var cell in hexGrid.allCells)
                {
                    lastSentEntropy[cell.center] = cell.entropy;
                }
                
                Debug.Log($"[初始化] 发送完整网格数据：{hexGrid.allCells.Count} 个cells");
            }
            // Delta更新：只发送变化的cells
            else if (useDeltaGridUpdate)
            {
                hexGridModel = new HexGridModel();
                int changedCount = 0;
                
                foreach (var cell in hexGrid.allCells)
                {
                    // 检查熵值是否变化（阈值0.1）
                    if (!lastSentEntropy.TryGetValue(cell.center, out float lastEntropy) || 
                        Mathf.Abs(cell.entropy - lastEntropy) > 0.1f)
                    {
                        hexGridModel.cells.Add(new HexCell(cell.center, cell.entropy));
                        lastSentEntropy[cell.center] = cell.entropy;
                        changedCount++;
                    }
                }
                
                // 如果没有变化，不发送
                if (changedCount == 0)
                {
                    return;
                }
                
                Debug.Log($"[Delta更新] 发送 {changedCount}/{hexGrid.allCells.Count} 个变化的cells");
            }
            else
            {
                // 禁用Delta：总是发送全部
                hexGridModel = new HexGridModel(hexGrid);
            }
            
            var dataPacks = new DataPacks()
            {
                type = PackType.grid_data,
                time_span = DateTime.Now.ToString(CultureInfo.InvariantCulture),
                pack_data_list = hexGridModel
            };

            var jsonData = JsonConvert.SerializeObject(dataPacks, new VectorConverter()) + "\n";
            var buffer = Encoding.UTF8.GetBytes(jsonData);
            stream.Write(buffer, 0, buffer.Length);
            // Debug.Log($"发送网格数据 {buffer.Length} 字节");
        }
        catch (Exception e)
        {
            Debug.LogWarning($"[发送] 发送网格数据失败: {e.Message}");
            isConnected = false;
        }
    }

    // 仅发送运行时数据
    public void SendRuntimeData()
    {
        if (!isConnected || autoScanners == null || autoScanners.Count == 0) return;

        try
        {
            var scanners = autoScanners.Select(autoScanner => autoScanner.scannerRuntime).ToList();
            var dataPacks = new DataPacks()
            {
                type = PackType.runtime_data,
                time_span = DateTime.Now.ToString(CultureInfo.InvariantCulture),
                pack_data_list = scanners,
            };

            var jsonData = JsonConvert.SerializeObject(dataPacks, new VectorConverter()) + "\n";
            var buffer = Encoding.UTF8.GetBytes(jsonData);
            stream.Write(buffer, 0, buffer.Length);
            // Debug.Log($"发送运行时数据 {buffer.Length} 字节"); // 优化：减少日志输出
        }
        catch (Exception e)
        {
            Debug.LogWarning($"[发送] 发送运行时数据失败: {e.Message}");
            isConnected = false;
        }
    }

    #endregion

    #region 接收数据

    // 接收服务器数据
    private void ReceiveData()
    {
        var buffer = new byte[8192];  // 优化：增大缓冲区 4096→8192
        while (isConnected)
        {
            try
            {
                if (stream.DataAvailable)
                {
                    var bytesRead = stream.Read(buffer, 0, buffer.Length);
                    if (bytesRead == 0)
                    {
                        // 连接已断开
                        Debug.LogWarning("[接收] 连接已断开（接收到0字节）");
                        isConnected = false;
                        break;
                    }
                    
                    var receivedText = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                    jsonBuffer.Append(receivedText);
                    
                    // 按换行符分割JSON对象（Python端每个JSON后都有\n）
                    var bufferText = jsonBuffer.ToString();
                    var jsonLines = bufferText.Split('\n');
                    
                    // 处理完整的JSON行
                    for (int i = 0; i < jsonLines.Length - 1; i++)
                    {
                        var jsonLine = jsonLines[i].Trim();
                        if (string.IsNullOrEmpty(jsonLine)) continue;
                        
                        try
                        {
                            var dataPacks = JsonConvert.DeserializeObject<DataPacks>(jsonLine);
                            
                            // 将数据放入队列，在主线程处理
                            lock (queueLock)
                            {
                                receivedDataQueue.Enqueue(dataPacks);
                            }
                        }
                        catch (JsonException jsonEx)
                        {
                            Debug.LogError($"[JSON错误] 解析失败: {jsonEx.Message}");
                            Debug.LogError($"[JSON错误] 数据 ({jsonLine.Length} 字符):");
                            Debug.LogError($"========== JSON开始 ==========");
                            Debug.LogError(jsonLine);
                            Debug.LogError($"========== JSON结束 ==========");
                        }
                    }
                    
                    // 保留最后一个不完整的部分
                    jsonBuffer.Clear();
                    jsonBuffer.Append(jsonLines[jsonLines.Length - 1]);
                }
                else
                {
                    Thread.Sleep(10);
                }
            }
            catch (Exception e)
            {
                Debug.LogWarning($"[接收] 接收数据错误: {e.Message}");
                isConnected = false;
                break;
            }
        }
        
        Debug.Log("[接收] 接收线程已退出");
    }

    // 处理接收的数据
    private void ProcessReceivedData(DataPacks dataPacks)
    {
        switch (dataPacks.type)
        {
            case PackType.runtime_data:
                var runtimeDatas =
                    JsonConvert.DeserializeObject<List<ScannerRuntime>>(dataPacks.pack_data_list.ToString());
                foreach (var scannerRuntime in runtimeDatas)
                {
                    foreach (var autoScanner in autoScanners.Where(autoScanner =>
                                 scannerRuntime != null && autoScanner.UavName.Equals(scannerRuntime.uavname)))
                    {
                        autoScanner.OnInit(scannerRuntime);
                    }
                }

                break;
            case PackType.grid_data:
                break;
            case PackType.config_data:
                var configData =
                    JsonConvert.DeserializeObject<ScannerConfig>(dataPacks.pack_data_list.ToString());
                foreach (var autoScanner in autoScanners)
                {
                    autoScanner.OnInitConfig(configData);
                }
                
                // 启动熵值计算
                if (hexGrid != null)
                {
                    hexGrid.IsStart = true;
                    Debug.Log("[配置] 已启动熵值计算");
                }

                break;
            case PackType.reset_env:
                // 重置环境（使用协程异步处理）
                Debug.Log("[重置] 收到环境重置命令");
                StartCoroutine(ResetEnvironmentCoroutine());
                break;
        }
    }

    // 重置环境（协程版本）
    private IEnumerator ResetEnvironmentCoroutine()
    {
        Debug.Log("[重置] 开始重置环境...");
        
        // 1. 停止发送数据、Leader运行和熵值计算
        isResetting = true;
        bool wasLeaderRunning = LeaderController != null && LeaderController.IsStart;
        bool wasHexGridRunning = hexGrid != null && hexGrid.IsStart;
        
        if (LeaderController != null)
        {
            LeaderController.IsStart = false;
        }
        if (hexGrid != null)
        {
            hexGrid.IsStart = false;
        }
        Debug.Log("[重置] 已停止发送数据、Leader和熵值计算");
        
        // 等待一帧，确保当前正在发送的数据完成
        yield return null;
        
        // 2. 重置网格熵值
        if (hexGrid != null)
        {
            hexGrid.ResetAllEntropy();
            Debug.Log("[重置] 网格熵值已重置");
        }
        
        // 3. 重置所有无人机位置
        if (autoScanners != null)
        {
            foreach (var scanner in autoScanners)
            {
                if (scanner != null)
                {
                    scanner.ResetPosition();
                }
            }
            Debug.Log($"[重置] 已重置 {autoScanners.Count} 个无人机");
        }
        
        // 4. 重置Leader
        if (LeaderController != null)
        {
            LeaderController.ResetLeader();
            Debug.Log("[重置] Leader已重置");
        }
        
        // 5. 清空Delta缓存，标记需要重新发送完整数据
        lastSentEntropy.Clear();
        hassentInitialGridData = false;
        
        // 6. 等待0.5秒，让重置操作完全生效
        yield return new WaitForSeconds(0.5f);
        
        // 7. 恢复发送数据、Leader运行和熵值计算
        isResetting = false;
        if (LeaderController != null && wasLeaderRunning)
        {
            LeaderController.IsStart = true;
        }
        if (hexGrid != null && wasHexGridRunning)
        {
            hexGrid.IsStart = true;
            Debug.Log("[重置] 已恢复熵值计算");
        }
        Debug.Log("[重置] 恢复发送数据和Leader运行");
        
        // 8. 立即发送完整网格数据和运行时数据
        Debug.Log("[重置] 发送完整数据到Python...");
        SendGridData();  // 发送完整网格数据
        yield return new WaitForSeconds(0.1f);
        SendRuntimeData();  // 发送运行时数据
        
        Debug.Log("[重置] ✅ 环境重置完成！");
    }

    #endregion

    #region GUI

    // 绘制GUI
    private void OnGUI()
    {
        // 限制按钮绘制区域
        GUILayout.BeginArea(buttonArea);

        // 设置GUI样式
        var buttonStyle = new GUIStyle(GUI.skin.button);
        buttonStyle.fontSize = 14;
        buttonStyle.fixedHeight = buttonHeight;

        // 根据连接状态显示不同按钮
        if (!isConnected)
        {
            if (GUILayout.Button("手动连接", buttonStyle))
            {
                StartConnection();
            }
        }
        else
        {
            if (GUILayout.Button("断开连接", buttonStyle))
            {
                Disconnect();
            }
        }
        
        // 重置按钮（测试用）
        GUILayout.Space(buttonSpacing);
        var resetStyle = new GUIStyle(GUI.skin.button);
        resetStyle.fontSize = 14;
        resetStyle.fixedHeight = buttonHeight;
        resetStyle.normal.textColor = Color.yellow;
        
        if (GUILayout.Button("🔄 重置环境", resetStyle))
        {
            Debug.Log("[测试] 用户点击重置按钮");
            StartCoroutine(ResetEnvironmentCoroutine());
        }

        // 显示当前连接状态和自动重连信息
        GUILayout.Space(buttonSpacing);
        var status = isConnected ? "状态: ✅ 已连接" : $"状态: ⏳ 未连接 (自动重连中...)";
        var statusColor = isConnected ? Color.green : Color.yellow;
        
        var labelStyle = new GUIStyle(GUI.skin.label) 
        { 
            fontSize = 12, 
            alignment = TextAnchor.MiddleLeft,
            normal = { textColor = statusColor }
        };
        GUILayout.Label(status, labelStyle);
        
        // 显示重连间隔
        if (!isConnected)
        {
            var intervalText = $"重连间隔: {autoReconnectInterval}秒";
            var intervalStyle = new GUIStyle(GUI.skin.label) 
            { 
                fontSize = 10, 
                alignment = TextAnchor.MiddleLeft,
                normal = { textColor = Color.gray }
            };
            GUILayout.Label(intervalText, intervalStyle);
        }
        
        // 显示重置状态
        if (isResetting)
        {
            var resetLabel = new GUIStyle(GUI.skin.label) 
            { 
                fontSize = 10, 
                normal = { textColor = Color.red }
            };
            GUILayout.Label("🔄 重置中...", resetLabel);
        }

        GUILayout.EndArea();
    }

    #endregion
}